<template>
  <el-input clearable :style="{ width }" :placeholder="t('component.icon.placeholder')" :class="prefixCls"
    v-model="currentSelect">
    <template #[item]="data" v-for="item in Object.keys(omit($slots, 'default', 'append'))">
      <slot :name="item" v-bind="data || {}"></slot>
    </template>
    <template #append>
      <el-popover v-model="visible" placement="bottom-end" trigger="click" :popper-class="`${prefixCls}-popover`"
        :width="310">
        <div class="flex justify-between">
          <el-input v-model="searchIcon" :placeholder="t('component.icon.search')" clearable
            @change="debounceHandleSearchChange" />
          <!-- @change="debounceHandleSearchChange" -->
        </div>
        <div v-if="getPaginationList.length">
          <el-scrollbar height="300px">
            <ul class="flex flex-wrap px-2">
              <li v-for="icon in getPaginationList" :key="icon"
                :class="currentSelect === icon ? 'border border-primary' : ''" class="p-2 w-1/8
                    cursor-pointer
                    mr-1
                    mt-1
                    flex
                    justify-center
                    items-center
                    border border-solid
                    hover:border-primary
                  " @click="handleClick(icon)" :title="icon">
                <!-- <Icon :icon="icon" :prefix="prefix" /> -->
                <Icon v-if="isSvgMode" :icon="`${icon}|svg`" />
                <Icon :icon="icon" v-else />
              </li>
            </ul>
          </el-scrollbar>
          <div class="flex py-2 items-center justify-center" v-if="getTotal >= pageSize">
            <el-pagination v-model:currentPage="getCurrentPage" v-model:page-size="pageSize"
              :page-sizes="[100, 200, 500, 1000]" small layout="sizes, prev, pager, next"
              @size-change="handleSizeChange" @current-change="handlePageChange" :total="getTotal" />
          </div>
        </div>

        <template #reference>
          <Icon :icon="!isSvgMode ? currentSelect : currentSelect ? `${currentSelect}|svg` : 'thumbnail|svg'"
            class="cursor-pointer px-2 py-1" />
        </template>
      </el-popover>
    </template>

  </el-input>
</template>

<script lang="ts" setup>
import { propTypes } from '@/utils/propTypes';
import { useI18n } from '@/hooks/web/useI18n';
import { useDesign } from '@/hooks/web/useDesign';
import { ref, unref, watch, watchEffect } from 'vue';
import { omit } from 'lodash-es';
import Icon from './Icon.vue';
import { usePagination } from '@/hooks/web/usePagination';
import svgIcons from 'virtual:svg-icons-names'
import iconsData from '../data/icons.data';
import { useCopyToClipboard } from '@/hooks/web/useCopyToClipboard';
import { useMessage } from '@/hooks/web/useMessage';
import { useDebounceFn } from '@vueuse/shared';

const emit = defineEmits(['change', 'update:modelValue']);


const props = defineProps({
  modelValue: propTypes.string,
  width: propTypes.string.def('100%'),
  pageSize: propTypes.number.def(100),
  mode: propTypes.oneOf<('svg' | 'iconify')[]>(['svg', 'iconify']).def('iconify'),
  copy: propTypes.bool.def(false),

})

const { t } = useI18n()
const { prefixCls } = useDesign('icon-picker');
const currentSelect = ref('');
const searchIcon = ref('')
const visible = ref(false);
const { clipboardRef, isSuccessRef } = useCopyToClipboard(props.modelValue);
const { createMessage } = useMessage();


const isSvgMode = props.mode === 'svg';
const icons = isSvgMode ? getSvgIcons() : getIcons();
const currentList = ref(icons);



watchEffect(() => {
  currentSelect.value = props.modelValue;
});

watch(
  () => currentSelect.value,
  v => {
    emit('update:modelValue', v);
    return emit('change', v);
  },
);

const { getPaginationList, getTotal, setCurrentPage, getCurrentPage, setPageSize } = usePagination(
  currentList,
  props.pageSize,
);

// console.log(svgIcons)
function getSvgIcons() {
  return svgIcons.map((icon: string) => icon.replace('icon-', ''));
}

function getIcons() {
  const data = iconsData as any;
  const prefix: string = data?.prefix ?? '';
  let result: string[] = [];
  if (prefix) {
    result = (data?.icons ?? []).map((item: string) => `${prefix}:${item}`);
  } else if (Array.isArray(iconsData)) {
    result = iconsData as string[];
  }
  return result;
}

function handleClick(icon: string) {
  currentSelect.value = icon;
  if (props.copy) {
    clipboardRef.value = icon;
    if (unref(isSuccessRef)) {
      createMessage.success(t('component.icon.copy'));
    }
  }
}

const debounceHandleSearchChange = useDebounceFn(handleSearchChange, 100);

function handleSearchChange(value: string) {
  if (!value) {
    setCurrentPage(1);
    currentList.value = icons;
    return;
  }
  currentList.value = icons.filter((item: string) => item.includes(value));
}

const handleSizeChange = (val: number) => {
  console.log(`${val} items per page`)
  setPageSize(val)
}
function handlePageChange(page: number) {
  setCurrentPage(page);
}

</script>